home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- File: HWSpecific.c
-
- Contains: ATM PCI hardware specific code
-
- Written by:
-
- Copyright: © 1994 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- To Do:
- ***********************************************************/
-
- /***********************************************************
- DEFINES
- ***********************************************************/
-
- /***********************************************************
- INCLUDES
- ***********************************************************/
-
- #include "PCIRoutines.h"
- #include "HWSpecific.h"
-
- /***********************************************************
- FUNCTION PROTOTYPES
- ***********************************************************/
-
- Boolean ABCVendorIsThisOurCard(RegEntryID *theID, UInt32 cardAddress);
- Boolean ABCVendorInit(RegEntryID *theID);
- void ABCVendorTerminate(void);
- SInt32 ABCVendorSetATMAddress(UInt8 *physicalAddress);
- void ABCVendorGetFactoryATMAddress(UInt8 *addressArray);
- UInt32 ABCVendorGetPeakCellRate();
- OSStatus ABCVendorTransmit(ConnectTableEntry* conn, UInt16 vpi, UInt16 vci, mblk_t* mp);
- OSStatus ABCVendorActivateVCI(ConnectTableEntry* conn);
- OSStatus ABCVendorDeactivateVCI(ConnectTableEntry* conn);
-
- static pascal void ABCVendorTxDTCallback(void *theParam);
- static pascal void ABCVendorRxDTCallback(void *theParam);
-
- InterruptMemberNumber ABCVendorISR(InterruptSetMember member, void *refCon, UInt32 theIntCount);
-
- /***********************************************************
- GLOBALS
- ***********************************************************/
-
- static ABCVendorCardSpecific* gABCVendorCardSpecificData;
-
- #ifdef LOOPBACK_TEST
- // temporary static data structure used for loopback testing.
- static struct _LoopBackMessageInfo {
- mblk_t* mp;
- UInt16 vpi;
- UInt16 vci;
- } gLoopBackMessageInfo;
- #endif
-
- /***********************************************************
- EXTERNS
- ***********************************************************/
-
- extern PortPrivateData *gPortPrivateData;
-
- /*
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- + +
- + F U N C T I O N S +
- + +
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine should determine if the card pointed to by theID can be used
- // by this driver. Before we can talk to the card, the card must be enabled. To
- // enable the card use the Expansion Manager calls to "set" the appropriate
- // address space bit for your card.
- //
- // Always turn off the card after the test has been made. Just because this routine
- // is executed, it does not mean that the card is going to be used by the system.
- //
- // Input:
- // theID - NameRegistry ID of our pci card
- // cardAddress - base address of our pci card
- //
- // Output:
- // returns true, if driver can work with the card
- // returns false, if driver cannot work with the card
- //
- //-----------------------------------------------------------------------------------------
- Boolean ABCVendorIsThisOurCard(RegEntryID *theID, UInt32 cardAddress)
- {
- UInt16 commandValue, newCommandValue, readValue;
- OSErr error;
-
- error = ExpMgrConfigReadWord(theID, kPCIConfigCommandRegister,&commandValue);
- newCommandValue = commandValue | kIOSpaceEnableBit; // turn on the card i/o space
- error = ExpMgrConfigWriteWord(theID, kPCIConfigCommandRegister, newCommandValue);
-
- // CARD REGISTERS ARE NOW ACCESSIBLE!
-
- // For I/O mapped cards...
- // In this example the readValue will be byte swapped by the Expansion Manager so it will
- // be in Big Endian format. You don't have to swap anything.
-
- // error = ExpMgrIOReadWord(theID, (LogicalAddress )(cardAddress + offset to your register) ,&readValue);
-
-
-
- // For memory mapped cards...
- // Since the card uses memory space, we can use the card using simple C pointers.
- // Remember that the card is little endian and the processor is big endian.
- // Long words (32 bits) and words (16 bits) must be swapped.
-
- // readValue = *((UInt16 *)(cardAddress + offset to your register));
-
- // turn card back off
- error = ExpMgrConfigWriteWord(theID, kPCIConfigCommandRegister, commandValue);
-
- return kTrue;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine first trys to allocate memory for our gABCVendorCardSpecificData.The
- // hardware should then be initialized. This routine also installs the interrupt
- // and initailizes the deferred task handlers.
- //
- // Input:
- //
- // Output:
- // kTrue, if initialization was successfull
- // kFalse, if initialization was not successfull
- //
- //-----------------------------------------------------------------------------------------
-
- Boolean ABCVendorInit(RegEntryID *theID)
- {
- OSStatus err;
- UInt32 spaceAllocated;
-
- #ifdef LOOPBACK_TEST
- gLoopBackMessageInfo.mp = (mblk_t*) NULL;
- #endif
-
- gABCVendorCardSpecificData = (ABCVendorCardSpecific*) PoolAllocateResident(sizeof(ABCVendorCardSpecific), kTrue);
- if (gABCVendorCardSpecificData == NULL) return kFalse;
-
- gPortPrivateData->cardSpecific = gABCVendorCardSpecificData;
-
- /*
- * kPCIConfigBase14Offset is the address at which the control
- * registers are mapped.
- */
- GetPCICardBaseAddress(&(gPortPrivateData->nodeEntryID), &(gABCVendorCardSpecificData->cardBaseAddr),
- kPCIConfigBase14Offset, &spaceAllocated);
-
-
- // initialize hardware, remember to turn on the address map bit in the Config Command Register
- // also if the card does dma then you need to turn on the dma bit
-
-
- gPortPrivateData->TxDeferredTaskCookie = OTCreateDeferredTask(ABCVendorTxDTCallback, NULL);
- gPortPrivateData->RxDeferredTaskCookie = OTCreateDeferredTask(ABCVendorRxDTCallback, NULL);
-
- // register interrupt handlers
- err = InstallISR();
- if (err != noErr)
- return kFalse;
-
- return kTrue;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine closes down the hardware. The memory for gABCVendorCardSpecificData is
- // deallocated. This routine undoes everything done in the initialize routine.
- //
- // Input:
- // NONE
- //
- // Output:
- // NONE
- //
- //-----------------------------------------------------------------------------------------
-
- void ABCVendorTerminate(void)
- {
- OSStatus err;
- mblk_t *thePacket;
-
- // turn off hardware
-
- // unregister interrupt handlers
- err = UninstallISR(); // ignore the error right now!
-
-
- OTDestroyDeferredTask(gPortPrivateData->TxDeferredTaskCookie);
- OTDestroyDeferredTask(gPortPrivateData->RxDeferredTaskCookie);
-
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine should set the physical address in the ATM hw. On initialization
- // we may have read our physical address out of a EPROM, but now somebody is
- // explicitly telling us to change our address.
- //
- // Input:
- // physicalAddress - multicast address (array of 6 bytes)
- //
- // Output:
- // returns no error
- //
- //-----------------------------------------------------------------------------------------
-
- SInt32 ABCVendorSetATMAddress(UInt8 *physicalAddress)
- {
- /* set the ATM NIC physical address */
- return kOTNoError;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine retrieves the factory ATM address.
- //
- // Input:
- // addressArray - address to place the factory ethernet address bytes
- //
- // Output:
- // NONE
- //
- //-----------------------------------------------------------------------------------------
- void ABCVendorGetFactoryATMAddress(UInt8 *addressArray)
- {
- /* get the ATM NIC physical address */
- addressArray[0] = 0x08;
- addressArray[1] = 0x00;
- addressArray[2] = 0x07;
- addressArray[3] = 0x11;
- addressArray[4] = 0x22;
- addressArray[5] = 0x33;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine retrieves the cards user peak cell rate in
- // terms of cells/second.
- //
- // Input:
- // NONE
- //
- // Output:
- // Peak Cell Rate.
- //
- //-----------------------------------------------------------------------------------------
- UInt32 ABCVendorGetPeakCellRate()
- {
- UInt32 rate;
-
- // rate = 365566; /* 155 Mb/s */
- rate = 330187; /* 140 Mb/s */
- // rate = 235849; /* 100 Mb/s */
-
- return rate;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine transmits an mp on the specfied vpi,vci.
- //
- // Input:
- // vpi - Virtual Path Identifier
- // vci - Virtual Circuit Identifier
- // mp - mblk to transmit
- //
- // Output:
- // kOTNoError, if good transmission
- // kFlowControl, if the VC can not accept the data.
- //
- //-----------------------------------------------------------------------------------------
- OSStatus ABCVendorTransmit(ConnectTableEntry* conn, UInt16 vpi, UInt16 vci, mblk_t* mp)
- {
- // Some drivers may have a more efficient way of retrieving
- // the connect table entry given the vpi and vci.
- if (conn==NULL)
- conn = find_connection(vpi, vci, kVCIOut);
-
- // transmit the message mp
-
- #ifdef LOOPBACK_TEST
- // this is for the loopback test
- if (gLoopBackMessageInfo.mp == (mblk_t*) NULL) {
- gLoopBackMessageInfo.mp = copymsg(mp);
- gLoopBackMessageInfo.vpi = vpi;
- gLoopBackMessageInfo.vci = vci;
- OTScheduleDeferredTask(gPortPrivateData->RxDeferredTaskCookie);
- }
- #endif
-
- freemsg(mp);
-
- return kOTNoError;
- }
-
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine activates the vpi,vci refered to
- // by the ConnectTableEntry specified.
- //
- // Input:
- // conn - ConnectTableEntry for VC to be activated
- //
- // Output:
- // kOTNoError
- //
- //-----------------------------------------------------------------------------------------
- OSStatus ABCVendorActivateVCI(ConnectTableEntry* conn)
- {
- // enable a VCI on the NIC
-
- return kOTNoError;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine deactivates the vpi,vci refered to
- // by the ConnectTableEntry specified.
- //
- // Input:
- // conn - ConnectTableEntry for VC to be activated
- //
- // Output:
- // kOTNoError
- //
- //-----------------------------------------------------------------------------------------
- OSStatus ABCVendorDeactivateVCI(ConnectTableEntry* conn)
- {
- // disable a VCI on the NIC
-
- return kOTNoError;
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine processes a deferred task caused due to
- // a transmission completion.
- //
- // Input:
- // theParam - the parameter passed when creating the
- // deferred task cookie, which is NULL in our case.
- //
- // Output:
- // NONE
- //
- //-----------------------------------------------------------------------------------------
- static pascal void ABCVendorTxDTCallback(void *theParam)
- {
-
- // free the last transmitted message
-
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine processes a deferred task caused due to
- // a packet reception. This routine should form an mblk
- // with the received packet and call ATMDLPI_unitdata_ind().
- //
- // Input:
- // theParam - the parameter passed when creating the
- // deferred task cookie, which is NULL in our case.
- //
- // Output:
- // NONE
- //
- //-----------------------------------------------------------------------------------------
- static pascal void ABCVendorRxDTCallback(void *theParam)
- {
- // get the received message from the card, create
- // a message block and send it up using
- // ATMDLPI_unitdata_ind()
-
- #ifdef LOOPBACK_TEST
- // this is for the loopback test
- if (gLoopBackMessageInfo.mp) {
- ATMDLPI_unitdata_ind((ConnectTableEntry*) NULL, gLoopBackMessageInfo.vpi, gLoopBackMessageInfo.vci,
- gLoopBackMessageInfo.mp);
- gLoopBackMessageInfo.mp = (mblk_t*) NULL;
- }
- #endif
- }
-
- //-----------------------------------------------------------------------------------------
- // Description:
- // This routine is the interrupt service routine for our card. Do necessary
- // stuff in isr then defer for a later time the bulk of the work. In the isr
- // you need to notify Open Transport that we are in an isr. The next step
- // is to clear whatever hw bit you need to in order to deassert the interrupt line.
- //
- // Input:
- // member - contains information about the pci interrupt member
- // refCon - this value was passed in during the installation of the isr, since
- // we have globals we do not need to use this
- //
- // Output:
- // return kIsrIsComplete always
- //
- //-----------------------------------------------------------------------------------------
-
- InterruptMemberNumber ABCVendorISR(InterruptSetMember member, void *refCon, UInt32 theIntCount)
- {
- mblk_t *thePacket;
-
- OTEnterInterrupt(); // open transport needs to be notified
- // when entering an interrupt
-
- // clear the bit that caused the interrupt
-
-
- if (0 /* it is a transmit interrupt */) {
-
- OTScheduleDeferredTask(gPortPrivateData->TxDeferredTaskCookie);
-
- }
-
- if (1 /* it is a receive interrupt */) {
-
- OTScheduleDeferredTask(gPortPrivateData->RxDeferredTaskCookie);
-
- }
-
-
- OTLeaveInterrupt(); // open transport needs to be notified
- // when leaving an interrupt
- return kIsrIsComplete;
- }
-
-